package com.appspot.abcensys.server.DAO.JDO;

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

import javax.jdo.PersistenceManager;

import com.appspot.abcensys.server.PMF;
import com.appspot.abcensys.server.DAO.AfwezigheidDAO;
import com.appspot.abcensys.shared.Afwezigheid;
import com.appspot.abcensys.shared.Gebruiker;

/**
 * JDO implementatie van de AfwezigheidDAO
 * 
 * @author Hugo Zonderland
 * @see com.appspot.abcensys.server.AfwezigheidDAO
 * @see com.appspot.abcensys.shared.Afwezigheid
 */

public class AfwezigheidDAO_JDO implements AfwezigheidDAO {

	private static final Logger log = Logger.getLogger(AfwezigheidDAO_JDO.class.getName());

	/**
	 * Default constuctor
	 */
	public AfwezigheidDAO_JDO() {

	}

	/**
	 * Slaat een Afwezig object op
	 * 
	 * @param Afwezigheid
	 *            object om op te slaan
	 * @return of opslaan is gelukt
	 */
	public boolean addAfwezigheid(Afwezigheid a) {
		boolean b = false;
		PersistenceManager pm = PMF.get().getPersistenceManager();
		try {
			pm.makePersistent(a);
			b = true;
		} finally {
			pm.close();
		}

		log.info("addAfwezigheid(" + a.toString() + ") | is opgeslagen: " + b);

		return b;
	}

	/**
	 * Haalt een afwezigheid object op.
	 * 
	 * @param Long
	 *            afwezigheidId
	 * @return Afwezigheid en anders null
	 */
	@SuppressWarnings("unchecked")
	public Afwezigheid getAfwezigheidById(Long afwezigheidId) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		String query = "SELECT FROM " + Afwezigheid.class.getName() + " WHERE id == " + afwezigheidId;
		ArrayList<Afwezigheid> afwezigheden = new ArrayList<Afwezigheid>(pm.detachCopyAll((List<Afwezigheid>) pm.newQuery(query).execute()));

		afwezigheden.size();
		pm.close();

		Afwezigheid afwezigheid = null;

		if (afwezigheden != null && !afwezigheden.isEmpty()) {
			afwezigheid = afwezigheden.get(0);
		}

		log.info("getAfwezigheidById(" + afwezigheidId + ") | Afwezigheid object: " + afwezigheid.toString());

		return afwezigheid;
	}

	/**
	 * Haalt een List met alle Afwezigheids registraties van de gebruiker op.
	 * 
	 * @param Gebruiker
	 *            om de afwezigheden voor op te halen
	 * @return List<Afwezigheid> met afwezigheids registraties
	 */
	@SuppressWarnings("unchecked")
	public ArrayList<Afwezigheid> getAfwezigheidVoorGebruiker(Gebruiker g) {
		ArrayList<Afwezigheid> afwezigheden = null;
		if (g.getType() == Gebruiker.TYPE_STUDENT) {
			PersistenceManager pm = PMF.get().getPersistenceManager();
			String query = "SELECT FROM " + Afwezigheid.class.getName() + " WHERE email == \"" + g.getEmail() + "\" ORDER BY lesId";
			afwezigheden = new ArrayList<Afwezigheid>(pm.detachCopyAll((List<Afwezigheid>) pm.newQuery(query).execute()));

			afwezigheden.size();
			pm.close();
		}

		log.info("getAfwezigheidVoorGebruiker(" + g.toString() + ") | Afwezigheden: " + afwezigheden.toString());

		return afwezigheden;
	}

	/**
	 * Haalt alle Afwezigheids registraties op bij een Les
	 * 
	 * @param Long
	 *            Les waar op gezocht word
	 * @return ArrayList<Afwezigheid> met Afwezigheid registraties
	 */
	@SuppressWarnings("unchecked")
	public ArrayList<Afwezigheid> getAfwezigheidPerLes(Long lesId) {
		ArrayList<Afwezigheid> afwezigheden = null;

		PersistenceManager pm = PMF.get().getPersistenceManager();
		String query = "SELECT FROM " + Afwezigheid.class.getName() + " WHERE lesId == " + lesId;
		afwezigheden = new ArrayList<Afwezigheid>(pm.detachCopyAll((List<Afwezigheid>) pm.newQuery(query).execute()));

		afwezigheden.size();
		pm.close();

		log.info("getAfwezigheidPerLes(" + lesId + ") | Afwezigheden: " + afwezigheden);

		return afwezigheden;
	}

	/**
	 * Dummy class
	 */
	public boolean updateAfwezigheid(Afwezigheid a) {
		return false;
	}

	/**
	 * Verwijderd een Afwezigheid object
	 * 
	 * @param Long
	 *            met de afwezigheidsId
	 * @return true wanneer gelukt, false wanneer niet
	 */
	public boolean verwijderAfwezigheid(Afwezigheid a) {
		boolean b = false;
		if (a != null) {
			try {
				PersistenceManager pm = PMF.get().getPersistenceManager();
				pm.deletePersistent(a);
				b = true;
			} catch (Exception ex) {
				System.out.println(ex.getMessage());
				ex.printStackTrace();
			}
		}

		log.info("verwijderAfwezigheid(" + a.toString() + ") | is verwijderd: " + b);

		return b;
	}

	/**
	 * Verwijderd een afwezigheid a.d.v. zijn Id en returnd of dit is gelukt
	 * Deze functie word gebruikt om objecten direct uit de Datastore te halen
	 * en dan te verwijderen. Anders volgt een
	 * "Transient instances cant be deleted" foutmelding. Zie:
	 * http://www.datanucleus.org/servlet/forum/viewthread_thread,5727
	 * 
	 * @param Long
	 *            met de afwezigheidsId
	 * @return true wanneer gelukt, false wanneer niet
	 */
	public boolean verwijderAfwezigheidByIdTrancient(Long afwezigheidId) {
		
		PersistenceManager pm = PMF.get().getPersistenceManager();
		Afwezigheid a = pm.getObjectById(Afwezigheid.class, afwezigheidId);
		
		boolean b = false;
		if (a != null) {
			try {
				pm.deletePersistent(a);
				b = true;
			} catch (Exception ex) {
				System.out.println(ex.getMessage());
				ex.printStackTrace();
			}
		}
		
		log.info("verwijderAfwezigheidByIdTrancient(" + afwezigheidId + ") | is verwijderd: " + b);
		
		return b;
	}

	/**
	 * Verwijderd een Afwezigheid object a.d.v. een Les Id en de email van een
	 * Gebruiker
	 * 
	 * @param String
	 *            met Les Id
	 * @param String
	 *            email adres van de Gebruiker
	 * @return true wanneer gelukt, false wanneer niet
	 */
	@SuppressWarnings("unchecked")
	public boolean verwijderAfwezigheidByLesIdAndGebruiker(int lesId, String email) {
		Long lLesId = Long.valueOf(lesId);

		PersistenceManager pm = PMF.get().getPersistenceManager();
		String query = "SELECT FROM " + Afwezigheid.class.getName() + " WHERE lesId == " + lLesId + " && email == \"" + email + "\"";
		ArrayList<Afwezigheid> afwezigheden = new ArrayList<Afwezigheid>(pm.detachCopyAll((List<Afwezigheid>) pm.newQuery(query).execute()));

		afwezigheden.size();
		pm.close();

		Afwezigheid a = null;
		boolean b = false;

		if (afwezigheden != null && !afwezigheden.isEmpty()) {
			a = afwezigheden.get(0);
			b = this.verwijderAfwezigheidByIdTrancient(a.getId());
		}
		
		log.info("verwijderAfwezigheidByLesIdAndGebruiker(" + lesId + ", " + email + ") | is verwijderd: " + b);

		return b;
	}

	/**
	 * Bepaald of een student afwezig is (geweest) in een les
	 * 
	 * @param Long
	 *            met de te controleren LesId
	 * @param String
	 *            met het email adres van de student
	 * @return true wanneer de student afwezig is/was, false wanneer niet
	 */
	@SuppressWarnings("unchecked")
	public boolean isStudentAfwezigInLes(Long lesId, String studentEmail) {
		return this.getAfwezigheidByLesAndStudent(lesId, studentEmail) != null;
	}
	
	/**
	 * Haalt een Afwezigheid registratie op van een student voor een bepaalde les
	 * 
	 * @param Long met lesId
	 * @param Sting studentEmail
	 * @return Afwezigheid registraties indien aanwezig, anders null
	 */
	public Afwezigheid getAfwezigheidByLesAndStudent(Long lesId, String studentEmail) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		String query = "SELECT FROM " + Afwezigheid.class.getName() + " WHERE email == \"" + studentEmail + "\" && lesId == " + lesId;
		ArrayList<Afwezigheid> afwezigheden = new ArrayList<Afwezigheid>(pm.detachCopyAll((List<Afwezigheid>) pm.newQuery(query).execute()));

		afwezigheden.size();
		pm.close();
		
		Afwezigheid a = null;
		
		if (afwezigheden != null && !afwezigheden.isEmpty()) {
			a = afwezigheden.get(0);
			log.info("getAfwezigheidByLesAndStudent(" + lesId + ", " + studentEmail + ") | Afwezigheid: " + a);
		}
		
		log.info("getAfwezigheidByLesAndStudent(" + lesId + ", " + studentEmail + ")");
		
		return a;
	}
}
